/*
 * BlackLightning.StormFront
 * Andy Tidball
 * 
 * Project: Black Lightning
 * Copyright: GNU General Public License
 */

using System;
using System.Text.RegularExpressions;
using BlackLightning.PluginLib.Modules;
using BLLib.Net;

namespace BlackLightning {
	/// <summary>
	/// Represents a connection to the StormFront front end program.
	/// </summary>
	internal class StormFront : FrontEnd {
		/// <summary>
		/// Creates a new StormFront connection.
		/// </summary>
		public StormFront()
			: base("\n", true, "\r\n", "\n") {
		}

		/// <summary>
		/// Gets the name of the front end's executable file.
		/// </summary>
		public override string ExecutableFilename {
			get {
				return "StormFront.exe";
			}
		}

		/// <summary>
		/// Sends a Packet down the connection.
		/// </summary>
		/// <param name="Packet">The packet to send down the connection.</param>
		public override void SendPacket(Packet Packet) {
			// create appropriate contextual information
			base.SendPacket(Packet, new BLPacketContext(Protocol.StormFront));
		}

		/// <summary>
		/// Creates a Packet from the front end and headed for either the game server or Black Lightning.
		/// </summary>
		/// <param name="Data">The data to initialize the packet with.</param>
		protected override Packet CreatePacket(string Data) {
			if (Data.StartsWith("<c>")) {
				// if the data starts with <c> then this is a command
				return new CommandPacket(Program.FrontEnd, (Data.StartsWith("<c>@") ? Program.BlackLightning : Program.GameServer), Data, new BLPacketContext(Protocol.StormFront));
			} else {
				// otherwise it's something else
				return new RawBLPacket(Program.FrontEnd, Program.GameServer, Data);
			}
		}

		/// <summary>
		/// Handshakes with the game server to login.
		/// </summary>
		/// <param name="Server">The new connection to the game server to handshake with.</param>
		public override void Handshake(Connection Server, bool FirstConnection) {
			string Received;
			if (FirstConnection) {
				// if this is the first connection, receive StormFront's login commands
				Regex LoginCmds = new Regex("<c>([0-9a-f]*)\n<c>(.*)\n");
				Received = base.Connection.Receive();
				while (!LoginCmds.IsMatch(Received)) {
					Received += base.Connection.Receive();
				}

				// store the identification
				Match M = LoginCmds.Match(Received);
				base.Identification = M.Groups[2].Captures[0].Value;

				// send the commands on to the server
				Server.Send(Received);
			} else {
				// if we're connecting for a second time, send our new key and stored identification
				Server.Send("<c>" + base.SalFile.Key + "\n<c>" + base.Identification + "\n");
			}

			// wait until we receive our settings info, and send that back to StormFront
			Regex SettingsInfo = new Regex(".*\n<settingsInfo.*\n");
			Received = Server.Receive();
			while (!SettingsInfo.IsMatch(Received)) {
				Received += Server.Receive();
			}
			base.Connection.Send(Received);
/*
			// wait for the blank line back
			Regex BlankLine = new Regex("<c>\n");
			Received = base.Connection.Receive();
			while (!BlankLine.IsMatch(Received)) {
				Received += base.Connection.Receive();
			}
*/		}
	}
}
